//
// Created by 郝羽 on 2017/12/15.
//

#ifndef RTC_XSWITCH2_INTER_ARRIVAL_TEST_HPP_HPP
#define RTC_XSWITCH2_INTER_ARRIVAL_TEST_HPP_HPP

#include "test/catch.hpp"

#include <algorithm>
#include "bwe/inter_arrival.hpp"

namespace bwe {
namespace test {

enum {
    kTimestampGroupLengthUs = 5000,
    kMinStep = 20,
    kTriggerNewGroupUs = kTimestampGroupLengthUs + kMinStep,
    kBurstThresholdMs = 5,
    kAbsSendTimeFraction = 18,
    kAbsSendTimeInterArrivalUpshift = 8,
    kInterArrivalShift = kAbsSendTimeFraction + kAbsSendTimeInterArrivalUpshift,
};

const double kRtpTimestampToMs = 1.0 / 90.0;
const double kAstToMs = 1000.0 / static_cast<double>(1 << kInterArrivalShift);

class InterArrivalTest {
public:
    InterArrival inter_arrival_;
    InterArrival inter_arrival_rtp_;
    InterArrival inter_arrival_ast_;
public:
    InterArrivalTest()
            : inter_arrival_(kTimestampGroupLengthUs / 1000, 1.0),
              inter_arrival_rtp_(MakeRtpTimestamp(kTimestampGroupLengthUs), kRtpTimestampToMs),
              inter_arrival_ast_(MakeAbsSendTime(kTimestampGroupLengthUs), kAstToMs) {}

    // Test that neither inter_arrival instance complete the timestamp group from
    // the given data.
    void ExpectFalse(int64_t timestamp_us, int64_t arrival_time_ms, size_t packet_size) {
        InternalExpectFalse(inter_arrival_rtp_, MakeRtpTimestamp(timestamp_us), arrival_time_ms, packet_size);
        InternalExpectFalse(inter_arrival_ast_, MakeAbsSendTime(timestamp_us), arrival_time_ms, packet_size);
    }

    // Test that both inter_arrival instances complete the timestamp group from
    // the given data and that all returned deltas are as expected (except
    // timestamp delta, which is rounded from us to different ranges and must
    // match within an interval, given in |timestamp_near].
    void ExpectTrue(int64_t timestamp_us,
                    int64_t arrival_time_ms,
                    size_t packet_size,
                    int64_t expected_timestamp_delta_us,
                    int64_t expected_arrival_time_delta_ms,
                    int expected_packet_size_delta,
                    uint32_t timestamp_near) {
        InternalExpectTrue(inter_arrival_rtp_,
                           MakeRtpTimestamp(timestamp_us),
                           arrival_time_ms,
                           packet_size,
                           MakeRtpTimestamp(expected_timestamp_delta_us),
                           expected_arrival_time_delta_ms,
                           expected_packet_size_delta,
                           timestamp_near);

        InternalExpectTrue(inter_arrival_ast_,
                           MakeAbsSendTime(timestamp_us),
                           arrival_time_ms,
                           packet_size,
                           MakeAbsSendTime(expected_timestamp_delta_us),
                           expected_arrival_time_delta_ms,
                           expected_packet_size_delta,
                           timestamp_near << 8);
    }

    void WrapTestHelper(int64_t wrap_start_us, uint32_t timestamp_near, bool unorderly_within_group) {
        // Step through the range of a 32 bit int, 1/4 at a time to not cause
        // packets close to wraparound to be judged as out of order.

        // G1
        int64_t arrival_time = 17;
        ExpectFalse(0, arrival_time, 1);

        // G2
        arrival_time += kBurstThresholdMs + 1;
        ExpectFalse(wrap_start_us / 4, arrival_time, 1);

        // G3
        arrival_time += kBurstThresholdMs + 1;
        ExpectTrue(wrap_start_us / 2, arrival_time, 1,
                   wrap_start_us / 4, kBurstThresholdMs + 1, 0,   // Delta G2-G1
                   0);

        // G4
        arrival_time += kBurstThresholdMs + 1;
        int64_t g4_arrival_time = arrival_time;
        ExpectTrue(wrap_start_us / 2 + wrap_start_us / 4, arrival_time, 1,
                   wrap_start_us / 4, kBurstThresholdMs + 1, 0,   // Delta G3-G2
                   timestamp_near);

        // G5
        arrival_time += kBurstThresholdMs + 1;
        ExpectTrue(wrap_start_us, arrival_time, 2,
                   wrap_start_us / 4, kBurstThresholdMs + 1, 0,   // Delta G4-G3
                   timestamp_near);
        for (int i = 0; i < 10; ++i) {
            // Slowly step across the wrap point.
            arrival_time += kBurstThresholdMs + 1;
            if (unorderly_within_group) {
                // These packets arrive with timestamps in decreasing order but are
                // nevertheless accumulated to group because their timestamps are higher
                // than the initial timestamp of the group.
                ExpectFalse(wrap_start_us + kMinStep * (9 - i), arrival_time, 1);
            } else {
                ExpectFalse(wrap_start_us + kMinStep * i, arrival_time, 1);
            }
        }
        int64_t g5_arrival_time = arrival_time;

        // This packet is out of order and should be dropped.
        arrival_time += kBurstThresholdMs + 1;
        ExpectFalse(wrap_start_us - 100, arrival_time, 100);

        // G6
        arrival_time += kBurstThresholdMs + 1;
        int64_t g6_arrival_time = arrival_time;
        ExpectTrue(wrap_start_us + kTriggerNewGroupUs, arrival_time, 10,
                   wrap_start_us / 4 + 9 * kMinStep,
                   g5_arrival_time - g4_arrival_time,
                   (2 + 10) - 1,  // Delta G5-G4
                   timestamp_near);

        // This packet is out of order and should be dropped.
        arrival_time += kBurstThresholdMs + 1;
        ExpectFalse(wrap_start_us + kTimestampGroupLengthUs, arrival_time, 100);

        // G7
        arrival_time += kBurstThresholdMs + 1;
        ExpectTrue(wrap_start_us + 2 * kTriggerNewGroupUs,
                   arrival_time, 100,
                // Delta G6-G5
                   kTriggerNewGroupUs - 9 * kMinStep,
                   g6_arrival_time - g5_arrival_time,
                   10 - (2 + 10),
                   timestamp_near);
    }

    void WrapTestHelper2(int64_t wrap_start_us, uint32_t timestamp_near, bool unorderly_within_group) {
        // Step through the range of a 32 bit int, 1/4 at a time to not cause
        // packets close to wraparound to be judged as out of order.

        // G1
        int64_t arrival_time = 17;
        ExpectFalse(0, arrival_time, 1);

        // G2
        arrival_time += kBurstThresholdMs + 1;
        ExpectFalse(wrap_start_us / 4, arrival_time, 1);

        // G3
        arrival_time += kBurstThresholdMs + 1;
        ExpectTrue(wrap_start_us / 2, arrival_time, 1,
                   wrap_start_us / 4, kBurstThresholdMs + 1, 0,   // Delta G2-G1
                   0);

        // G4
        arrival_time += kBurstThresholdMs + 1;
        int64_t g4_arrival_time = arrival_time;
        ExpectTrue(wrap_start_us / 2 + wrap_start_us / 4, arrival_time, 1,
                   wrap_start_us / 4, kBurstThresholdMs + 1, 0,   // Delta G3-G2
                   timestamp_near);

        // G5
        arrival_time += kBurstThresholdMs + 1;
        ExpectTrue(wrap_start_us, arrival_time, 2,
                   wrap_start_us / 4, kBurstThresholdMs + 1, 0,   // Delta G4-G3
                   timestamp_near);
        for (int i = 0; i < 10; ++i) {
            // Slowly step across the wrap point.
            // slowly increasing arrival_time
            arrival_time += 1;
            if (unorderly_within_group) {
                // These packets arrive with timestamps in decreasing order but are
                // nevertheless accumulated to group because their timestamps are higher
                // than the initial timestamp of the group.
                ExpectFalse(wrap_start_us + kMinStep * (9 - i), arrival_time, 1);
            } else {
                ExpectFalse(wrap_start_us + kMinStep * i, arrival_time, 1);
            }
        }
        int64_t g5_arrival_time = arrival_time;

        // This packet is out of order and should be dropped.
        arrival_time += kBurstThresholdMs + 1;
        ExpectFalse(wrap_start_us - 100, arrival_time, 100);

        // G6
        arrival_time += kBurstThresholdMs + 1;
        int64_t g6_arrival_time = arrival_time;
        ExpectTrue(wrap_start_us + kTriggerNewGroupUs, arrival_time, 10,
                   wrap_start_us / 4 + 9 * kMinStep,
                   g5_arrival_time - g4_arrival_time,
                   (2 + 10) - 1,  // Delta G5-G4
                   timestamp_near);

        // This packet is out of order and should be dropped.
        arrival_time += kBurstThresholdMs + 1;
        ExpectFalse(wrap_start_us + kTimestampGroupLengthUs, arrival_time, 100);

        // G7
        arrival_time += kBurstThresholdMs + 1;
        ExpectTrue(wrap_start_us + 2 * kTriggerNewGroupUs,
                   arrival_time, 100,
                // Delta G6-G5
                   kTriggerNewGroupUs - 9 * kMinStep,
                   g6_arrival_time - g5_arrival_time,
                   10 - (2 + 10),
                   timestamp_near);
    }

private:
    static uint32_t MakeRtpTimestamp(int64_t us) {
        return static_cast<uint32_t>(static_cast<uint64_t>(us * 90 + 500) / 1000);
    }

    static uint32_t MakeAbsSendTime(int64_t us) {
        uint32_t absolute_send_time = static_cast<uint32_t>(
                                              ((static_cast<uint64_t>(us) << 18) + 500000) / 1000000) & 0x00FFFFFFul;
        return absolute_send_time << 8;
    }

    static void InternalExpectFalse(InterArrival& inter_arrival,
                                    uint32_t timestamp,
                                    int64_t arrival_time_ms,
                                    size_t packet_size) {
        uint32_t dummy_timestamp = 101;
        int64_t dummy_arrival_time_ms = 303;
        int dummy_packet_size = 909;
        //std::cout << "timestamp " << timestamp << std::endl;
        bool computed = inter_arrival.ComputeDelta(
                dummy_timestamp, dummy_arrival_time_ms, dummy_packet_size,
                timestamp, arrival_time_ms, packet_size, arrival_time_ms);
        REQUIRE(!computed);
        REQUIRE(dummy_timestamp == 101ul);
        REQUIRE(dummy_arrival_time_ms == 303);
        REQUIRE(dummy_packet_size == 909);
    };

    static void InternalExpectTrue(InterArrival& inter_arrival,
                                   uint32_t timestamp,
                                   int64_t arrival_time_ms,
                                   size_t packet_size,
                                   uint32_t expected_timestamp_delta,
                                   int64_t expected_arrival_time_delta_ms,
                                   int expected_packet_size_delta,
                                   int32_t timestamp_near) {
        uint32_t delta_timestamp = 101;
        int64_t delta_arrival_time_ms = 303;
        int delta_packet_size = 909;
        //std::cout << "timestamp " << timestamp << std::endl;
        bool computed = inter_arrival.ComputeDelta(
                delta_timestamp, delta_arrival_time_ms, delta_packet_size,
                timestamp, arrival_time_ms, packet_size, arrival_time_ms);
        REQUIRE(computed);
        int32_t timestamp_diff = expected_timestamp_delta - delta_timestamp;
        //std::cout << "timestamp_diff = " << timestamp_diff << " near: " << timestamp_near << " -near: " << -timestamp_near << std::endl;
        REQUIRE(std::abs(timestamp_diff) <= timestamp_near);
        REQUIRE(expected_arrival_time_delta_ms == delta_arrival_time_ms);
        REQUIRE(expected_packet_size_delta == delta_packet_size);
    };

};

TEST_CASE("first packet", "[inter-arrival]") {
    InterArrivalTest test;
    test.ExpectFalse(0, 17, 1);
}


TEST_CASE("first group", "[inter-arrival]") {
    InterArrivalTest test;
    // G1
    int64_t arrival_time = 17;
    int64_t g1_arrival_time = arrival_time;
    test.ExpectFalse(0, arrival_time, 1);

    // G2
    arrival_time += kBurstThresholdMs + 1;
    int64_t g2_arrival_time = arrival_time;
    test.ExpectFalse(kTriggerNewGroupUs, arrival_time, 2);

    // G3
    // Only once the first packet of the third group arrives, do we see the deltas
    // between the first two.
    arrival_time += kBurstThresholdMs + 1;
    test.ExpectTrue(2 * kTriggerNewGroupUs, arrival_time, 1,
                    kTriggerNewGroupUs, g2_arrival_time - g1_arrival_time, 1,
                    0);
}

TEST_CASE("second group", "[inter-arrival]") {
    InterArrivalTest test;
    // G1
    int64_t arrival_time = 17;
    int64_t g1_arrival_time = arrival_time;
    test.ExpectFalse(0, arrival_time, 1);

    // G2
    arrival_time += kBurstThresholdMs + 1;
    int64_t g2_arrival_time = arrival_time;
    test.ExpectFalse(kTriggerNewGroupUs, arrival_time, 2);

    // G3
    arrival_time += kBurstThresholdMs + 1;
    int64_t g3_arrival_time = arrival_time;
    test.ExpectTrue(2 * kTriggerNewGroupUs, arrival_time, 1,
                    kTriggerNewGroupUs, g2_arrival_time - g1_arrival_time, 1,     // Delta G2-G1
                    0);

    // G4
    // First packet of 4th group yields deltas between group 2 and 3.
    arrival_time += kBurstThresholdMs + 1;
    test.ExpectTrue(3 * kTriggerNewGroupUs, arrival_time, 2,
                    kTriggerNewGroupUs, g3_arrival_time - g2_arrival_time, -1,    // Delta G3-G2
                    0);
}

TEST_CASE("accumulated group", "[inter-arrival]") {
    InterArrivalTest test;
    // G1
    int64_t arrival_time = 17;
    int64_t g1_arrival_time = arrival_time;
    test.ExpectFalse(0, arrival_time, 1);

    // G2
    arrival_time += kBurstThresholdMs + 1;
    test.ExpectFalse(kTriggerNewGroupUs, 28, 2);
    int64_t timestamp = kTriggerNewGroupUs;
    for (int i = 0; i < 10; ++i) {
        // A bunch of packets arriving within the same group.
        arrival_time += kBurstThresholdMs + 1;
        timestamp += kMinStep;
        test.ExpectFalse(timestamp, arrival_time, 1);
    }
    int64_t g2_arrival_time = arrival_time;
    int64_t g2_timestamp = timestamp;

    // G3
    arrival_time = 500;
    test.ExpectTrue(2 * kTriggerNewGroupUs, arrival_time, 100,
                    g2_timestamp, g2_arrival_time - g1_arrival_time, (2 + 10) - 1,   // Delta G2-G1
                    0);
}

TEST_CASE("out of order packet", "[inter-arrival]") {
    InterArrivalTest test;
    // G1
    int64_t arrival_time = 17;
    int64_t timestamp = 0;
    test.ExpectFalse(timestamp, arrival_time, 1);
    int64_t g1_timestamp = timestamp;
    int64_t g1_arrival_time = arrival_time;

    // G2
    arrival_time += 11;
    timestamp += kTriggerNewGroupUs;
    test.ExpectFalse(timestamp, 28, 2);
    for (int i = 0; i < 10; ++i) {
        arrival_time += kBurstThresholdMs + 1;
        timestamp += kMinStep;
        test.ExpectFalse(timestamp, arrival_time, 1);
    }
    int64_t g2_timestamp = timestamp;
    int64_t g2_arrival_time = arrival_time;

    // This packet is out of order and should be dropped.
    arrival_time = 281;
    test.ExpectFalse(g1_timestamp, arrival_time, 100);

    // G3
    arrival_time = 500;
    timestamp = 2 * kTriggerNewGroupUs;
    test.ExpectTrue(timestamp, arrival_time, 100,
                    g2_timestamp - g1_timestamp, g2_arrival_time - g1_arrival_time, (2 + 10) - 1,    // Delta G2-G1
                    0);
}

TEST_CASE("out of order within group", "[inter-arrival]") {
    InterArrivalTest test;
    // G1
    int64_t arrival_time = 17;
    int64_t timestamp = 0;
    test.ExpectFalse(timestamp, arrival_time, 1);
    int64_t g1_timestamp = timestamp;
    int64_t g1_arrival_time = arrival_time;

    // G2
    timestamp += kTriggerNewGroupUs;
    arrival_time += 11;
    test.ExpectFalse(timestamp, 28, 2);
    timestamp += 10 * kMinStep;
    int64_t g2_timestamp = timestamp;

    for (int i = 0; i < 10; ++i) {
        // These packets arrive with timestamps in decreasing order but are
        // nevertheless accumulated to group because their timestamps are higher
        // than the initial timestamp of the group.
        arrival_time += kBurstThresholdMs + 1;
        test.ExpectFalse(timestamp, arrival_time, 1);
        timestamp -= kMinStep;
    }
    int64_t g2_arrival_time = arrival_time;

    // However, this packet is deemed out of order and should be dropped.
    arrival_time = 281;
    timestamp = g1_timestamp;
    test.ExpectFalse(timestamp, arrival_time, 100);

    // G3
    timestamp = 2 * kTriggerNewGroupUs;
    arrival_time = 500;
    test.ExpectTrue(timestamp, arrival_time, 100,
                    g2_timestamp - g1_timestamp, g2_arrival_time - g1_arrival_time, (2 + 10) - 1,
                    0);
}

TEST_CASE("two burst", "[inter-arrival]") {
    InterArrivalTest test;
    // G1
    int64_t g1_arrival_time = 17;
    test.ExpectFalse(0, g1_arrival_time, 1);

    // G2
    int64_t timestamp = kTriggerNewGroupUs;
    int64_t arrival_time = 100;  // Simulate no packets arriving for 100 ms.
    for (int i = 0; i < 10; ++i) {
        // A bunch of packets arriving in one burst (within 5 ms apart).
        timestamp += 30000;
        arrival_time += kBurstThresholdMs;
        test.ExpectFalse(timestamp, arrival_time, 1);
    }
    int64_t g2_arrival_time = arrival_time;
    int64_t g2_timestamp = timestamp;

    // G3
    timestamp += 30000;
    arrival_time += kBurstThresholdMs + 1;
    test.ExpectTrue(timestamp, arrival_time, 100,
                    g2_timestamp, g2_arrival_time - g1_arrival_time, 10 - 1,  // Delta G2-G1
                    0);
}

TEST_CASE("no burst", "[inter-arrival]") {
    InterArrivalTest test;
    // G1
    test.ExpectFalse(0, 17, 1);

    // G2
    int64_t timestamp = kTriggerNewGroupUs;
    int64_t arrival_time = 28;
    test.ExpectFalse(timestamp, arrival_time, 2);

    // G3
    test.ExpectTrue(kTriggerNewGroupUs + 30000, arrival_time + kBurstThresholdMs + 1, 100,
                    timestamp - 0, arrival_time - 17, 2 - 1,  // Delta G2-G1
                    0);
}

// Yields 0xfffffffe when converted to internal representation in
// inter_arrival_rtp_ and inter_arrival_ast_ respectively.

static const int64_t kStartRtpTimestampWrapUs = 47721858827;
static const int64_t kStartAbsSendTimeWrapUs  =    63999995;

TEST_CASE("rtp timestamp wrap", "[inter-arrival][wrap]") {
    InterArrivalTest test;
    test.WrapTestHelper(kStartRtpTimestampWrapUs, 1, false);
}

TEST_CASE("abs-send-time wrap", "[inter-arrival][wrap]") {
    InterArrivalTest test;
    test.WrapTestHelper(kStartAbsSendTimeWrapUs, 1, false);
}

TEST_CASE("rtp timestamp wrap with out of order", "[inter-arrival][wrap]") {
    InterArrivalTest test;
    test.WrapTestHelper(kStartRtpTimestampWrapUs, 1, true);
}

TEST_CASE("abs-send-time wrap with out of order", "[inter-arrival][wrap]") {
    InterArrivalTest test;
    test.WrapTestHelper(kStartAbsSendTimeWrapUs, 1, true);
}

//TEST_CASE("custom re-order", "[inter-arrival]") {
//    InterArrivalTest test;
//    // G1
//    test.ExpectFalse(0, 0, 1);
//    // G2
//    //               5.02ms
//    test.ExpectFalse(5020,                7, 1); // ts_diff = 5.02ms, t_diff = 7ms, ts_first_diff = 5.02ms, ts_first_diff > 5ms, new group
//    //               10.06ms
//    test.ExpectFalse(5020 * 2 + kMinStep,11, 1); // ts_diff = 5.04ms, t_diff = 4ms, same group (t_ts_diff < 0 t_diff_ms < 5ms)
//    // out of order but still belongs to G2
//    //               10.04ms
//    test.ExpectFalse(5020 * 2,           17, 1); // ts_diff = -0.02ms, t_diff = 6ms, ts_first_diff = 5.02ms
//                                                 // webrtc will put this packet into new group, then get a large delta because there is a re-order
//    // G4
//    test.ExpectTrue(5020 * 3,            23, 1,
//                    5020 * 2 + kMinStep, 17, 2,
//                    0);
//}

TEST_CASE("cutstom wrap", "[inter-arrival][wrap]") {
    InterArrivalTest test;
    // G1
    test.ExpectFalse(kStartAbsSendTimeWrapUs / 4 * 3, 0, 1);
    // G2
    test.ExpectFalse(kStartAbsSendTimeWrapUs - kTriggerNewGroupUs, 6, 1);
    // G3
    //
    test.ExpectTrue(kStartAbsSendTimeWrapUs, 12, 1, // ts_diff = 5.02ms, t_diff = 7ms, ts_first_diff = 5.02ms, ts_first_diff > 5ms, new group
                    kStartAbsSendTimeWrapUs / 4 - kTriggerNewGroupUs, 6, 0,
                    1);
    test.ExpectFalse(kStartAbsSendTimeWrapUs + 20, 12, 1);

    // G4
    test.ExpectTrue(kStartAbsSendTimeWrapUs + kTriggerNewGroupUs, 18, 1,
                    kTriggerNewGroupUs + 20, 6, 1,
                    1);
}

// this is commented since we use system clock as arrival time
// it is impossible to have system clock jumps
//TEST_CASE("postive arrival time jump", "[inter-arrival][jump]") {
//    InterArrivalTest test;
//
//    const size_t kPacketSize = 1000;
//    uint32_t send_time_ms = 10000;
//    int64_t arrival_time_ms = 20000;
//    int64_t system_time_ms = 30000;
//
//    uint32_t send_delta;
//    int64_t arrival_delta;
//    int size_delta;
//    REQUIRE_FALSE(test.inter_arrival_->ComputeDeltas(
//            send_delta, arrival_delta, size_delta,
//            send_time_ms, arrival_time_ms, system_time_ms, kPacketSize));
//
//    const int kTimeDeltaMs = 30;
//    send_time_ms += kTimeDeltaMs;
//    arrival_time_ms += kTimeDeltaMs;
//    system_time_ms += kTimeDeltaMs;
//    REQUIRE_FALSE(test.inter_arrival_->ComputeDeltas(
//            send_delta, arrival_delta, size_delta,
//            send_time_ms, arrival_time_ms, system_time_ms, kPacketSize));
//
//    send_time_ms += kTimeDeltaMs;
//    arrival_time_ms += kTimeDeltaMs + InterArrival::kArrivalTimeOffsetThresholdMs;
//    system_time_ms += kTimeDeltaMs;
//    REQUIRE(inter_arrival_->ComputeDeltas(
//            send_delta, arrival_delta, size_delta,
//            send_time_ms, arrival_time_ms, system_time_ms, kPacketSize));
//    REQUIRE(static_cast<int>(send_delta) == kTimeDeltaMs);
//    REQUIRE(arrival_delta == kTimeDeltaMs);
//    REQUIRE(size_delta == 0);
//
//    send_time_ms += kTimeDeltaMs;
//    arrival_time_ms += kTimeDeltaMs;
//    system_time_ms += kTimeDeltaMs;
//    // The previous arrival time jump should now be detected and cause a reset.
//    REQUIRE_FALSE(inter_arrival_->ComputeDeltas(
//            send_delta, arrival_delta, size_delta
//            send_time_ms, arrival_time_ms, system_time_ms, kPacketSize));
//
//    // The two next packets will not give a valid delta since we're in the initial
//    // state.
//    for (int i = 0; i < 2; ++i) {
//    send_time_ms += kTimeDeltaMs;
//    arrival_time_ms += kTimeDeltaMs;
//    system_time_ms += kTimeDeltaMs;
//    EXPECT_FALSE(inter_arrival_->ComputeDeltas(
//            send_time_ms, arrival_time_ms, system_time_ms, kPacketSize, &send_delta,
//            &arrival_delta, &size_delta));
//    }
//
//    send_time_ms += kTimeDeltaMs;
//    arrival_time_ms += kTimeDeltaMs;
//    system_time_ms += kTimeDeltaMs;
//    EXPECT_TRUE(inter_arrival_->ComputeDeltas(
//            send_time_ms, arrival_time_ms, system_time_ms, kPacketSize, &send_delta,
//            &arrival_delta, &size_delta));
//    EXPECT_EQ(kTimeDeltaMs, static_cast<int>(send_delta));
//    EXPECT_EQ(kTimeDeltaMs, arrival_delta);
//    EXPECT_EQ(size_delta, 0);
//}

// same reason with upper case
//TEST_CASE("negative arrival time jump", "[inter-arrival][jump]") {
//const size_t kPacketSize = 1000;
//uint32_t send_time_ms = 10000;
//int64_t arrival_time_ms = 20000;
//int64_t system_time_ms = 30000;
//
//uint32_t send_delta;
//int64_t arrival_delta;
//int size_delta;
//EXPECT_FALSE(inter_arrival_->ComputeDeltas(
//        send_time_ms, arrival_time_ms, system_time_ms, kPacketSize, &send_delta,
//        &arrival_delta, &size_delta));
//
//const int kTimeDeltaMs = 30;
//send_time_ms += kTimeDeltaMs;
//arrival_time_ms += kTimeDeltaMs;
//system_time_ms += kTimeDeltaMs;
//EXPECT_FALSE(inter_arrival_->ComputeDeltas(
//        send_time_ms, arrival_time_ms, system_time_ms, kPacketSize, &send_delta,
//        &arrival_delta, &size_delta));
//
//send_time_ms += kTimeDeltaMs;
//arrival_time_ms += kTimeDeltaMs;
//system_time_ms += kTimeDeltaMs;
//EXPECT_TRUE(inter_arrival_->ComputeDeltas(
//        send_time_ms, arrival_time_ms, system_time_ms, kPacketSize, &send_delta,
//        &arrival_delta, &size_delta));
//EXPECT_EQ(kTimeDeltaMs, static_cast<int>(send_delta));
//EXPECT_EQ(kTimeDeltaMs, arrival_delta);
//EXPECT_EQ(size_delta, 0);
//
//// Three out of order will fail, after that we will be reset and two more will
//// fail before we get our first valid delta after the reset.
//arrival_time_ms -= 1000;
//for (int i = 0; i < InterArrival::kReorderedResetThreshold + 3; ++i) {
//send_time_ms += kTimeDeltaMs;
//arrival_time_ms += kTimeDeltaMs;
//system_time_ms += kTimeDeltaMs;
//// The previous arrival time jump should now be detected and cause a reset.
//EXPECT_FALSE(inter_arrival_->ComputeDeltas(
//        send_time_ms, arrival_time_ms, system_time_ms, kPacketSize, &send_delta,
//        &arrival_delta, &size_delta));
//}
//
//send_time_ms += kTimeDeltaMs;
//arrival_time_ms += kTimeDeltaMs;
//system_time_ms += kTimeDeltaMs;
//EXPECT_TRUE(inter_arrival_->ComputeDeltas(
//        send_time_ms, arrival_time_ms, system_time_ms, kPacketSize, &send_delta,
//        &arrival_delta, &size_delta));
//EXPECT_EQ(kTimeDeltaMs, static_cast<int>(send_delta));
//EXPECT_EQ(kTimeDeltaMs, arrival_delta);
//EXPECT_EQ(size_delta, 0);
//}
//
}
}

#endif //RTC_XSWITCH2_INTER_ARRIVAL_TEST_HPP_HPP
